package com.tool.util;

import com.tool.bean.DataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.swing.JOptionPane;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DbUtil
{
	
	private static transient Log log = LogFactory.getLog(DbUtil.class);
	
	private static final Map DS_MAP = getDataSourceMap();
	
	public static List getTableNames(Connection conn)
	{
		List list = new ArrayList();
		try
		{
			DatabaseMetaData dbmd = conn.getMetaData();
			ResultSet rs = dbmd.getTables(null, null, null,
					new String[] { "TABLE" });
			while (rs.next())
			{
				list.add(rs.getString(3));
			}
			rs.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return list;
	}
	
	public static List getColumns(ResultSet rs)
	{
		List list = new ArrayList();
		List names = new ArrayList();
		try
		{
			ResultSetMetaData rsmd = rs.getMetaData();
			for (int i = 1; i <= rsmd.getColumnCount(); i++)
			{
				String colName = rsmd.getColumnLabel(i).toUpperCase();
				String javaName = StringUtil.getCamel(colName);
				String colType = rsmd.getColumnTypeName(i).toUpperCase();
				String javaType = TypesUtil.getProperty(colType);
				if (!names.contains(colName))
				{
					names.add(colName);
					list.add(colName + "," + colType + "," + javaName + ","
							+ javaType);
				}
			}
		}
		catch (Exception e)
		{
			JOptionPane.showMessageDialog(null, e.getMessage());
			e.printStackTrace();
		}
		return list;
	}
	
	public static List getColumns(Connection conn, String tableName)
	{
		List list = new ArrayList();
		try
		{
			String sql = "select * from " + tableName + " where 1=2";
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(sql);
			ResultSetMetaData rsmd = rs.getMetaData();
			for (int i = 1; i <= rsmd.getColumnCount(); i++)
			{
				String colName = rsmd.getColumnLabel(i).toUpperCase();
				String colTypeName = TypesUtil.getProperty(rsmd
						.getColumnTypeName(i).toUpperCase());
				list.add(colName + "," + colTypeName);
			}
			rs.close();
			if (log.isDebugEnabled())
			{
				log.debug("------------------------------------");
				log.debug("获取数据库表:" + tableName + "结构如下");
				log.debug(list);
				log.debug("------------------------------------");
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return list;
	}
	
	public static Map<String, String> getColumnsCommon(Connection conn,
			String tableName)
	{
		Map<String, String> map = new HashMap<String, String>();
		try
		{
			String sql = " SELECT	CONCAT(COLUMN_NAME , '@' , COLUMN_COMMENT) as column_comment FROM information_schema. COLUMNS ";
			sql += " where table_name  = '" + tableName + "'";
			// + "' and table_schema = '" + dataBase + "'";
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(sql);
			
			while (rs.next())
			{
				String colName = rs.getString("column_comment");
				String[] cols = colName.split("@");
				if (cols != null)
				{
					String col = StringUtil.lowerFirst(StringUtil
							.getBeanName(cols[0]));
					String label = "";
					label = col;
					if (2 == cols.length)
					{
						label = cols[1];
					}
					map.put(col, label);
				}
			}
			rs.close();
			if (log.isDebugEnabled())
			{
				log.debug("------------------------------------");
				log.debug("获取数据库表:" + tableName + " 字段对应注释如下");
				log.debug(map);
				log.debug("------------------------------------");
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return map;
	}
	
	public static boolean isIdAutoIncrement(Connection conn, String tableName)
	{
		boolean result = true;
		try
		{
			String sql = "select * from `" + tableName + "` where 1=2";
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(sql);
			ResultSetMetaData rsmd = rs.getMetaData();
			int colIndex = 0;
			for (int i = 1; i <= rsmd.getColumnCount(); i++)
			{
				String colName = rsmd.getColumnLabel(i).toUpperCase();
				if ("ID".equals(colName))
				{
					colIndex = i;
				}
			}
			rs.close();
			if (colIndex > 0)
			{
				result = rsmd.isAutoIncrement(colIndex);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return result;
	}
	
	public static String[] getDataSource()
	{
		return (String[]) DS_MAP.keySet().toArray(new String[0]);
	}
	
	private static Map getDataSourceMap()
	{
		Map map = new HashMap();
		try
		{
			String path = ConfigUtil.getProperty("jdbc.file");
			Properties props = new Properties();
			
			InputStream is = DbUtil.class.getClassLoader().getResourceAsStream(
					path);
			InputStreamReader isr = new InputStreamReader(is,
					Charset.forName("utf-8"));
			// Reader reader = new InputStreamReader(new FileInputStream(new
			// File(
			// path)), Charset.forName("utf-8"));
			props.load(isr);
			// reader.close();
			String[] tmps = props.getProperty("datasource").split(",");
			for (int i = 0; i < tmps.length; i++)
			{
				DataSource ds = new DataSource();
				ds.setName(tmps[i]);
				ds.setDriverClassName(props.getProperty(tmps[i]
						+ ".driverClassName"));
				ds.setUrl(props.getProperty(tmps[i] + ".url"));
				ds.setUsername(props.getProperty(tmps[i] + ".username"));
				ds.setPassword(props.getProperty(tmps[i] + ".password"));
				map.put(tmps[i], ds);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return map;
	}
	
	public static DataSource getDataSource(String ds)
	{
		return (DataSource) DS_MAP.get(ds);
	}
	
	public static void main(String[] args)
		throws Exception
	{
	}
	
	public static Connection getConnection(String ds)
	{
		return getConnection(getDataSource(ds));
	}
	
	public static Connection getConnection(DataSource ds)
	{
		try
		{
			Class.forName(ds.getDriverClassName());
			return DriverManager.getConnection(ds.getUrl(), ds.getUsername(),
					ds.getPassword());
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	public static void closeJdbc(ResultSet[] rss, Statement[] stmts,
			Connection[] conns)
	{
		if ((rss != null) && (rss.length > 0))
		{
			for (int i = 0; i < rss.length; i++)
			{
				try
				{
					rss[i].close();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
		if ((stmts != null) && (stmts.length > 0))
		{
			for (int i = 0; i < stmts.length; i++)
			{
				try
				{
					stmts[i].close();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
		if ((conns != null) && (conns.length > 0))
		{
			for (int i = 0; i < conns.length; i++)
			{
				try
				{
					conns[i].close();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
	}
}
